package cn.ch.user.service.impl;

import cn.ch.basic.constant.BaseConstant;
import cn.ch.basic.dto.RegisterDto;
import cn.ch.basic.exception.BusinessException;
import cn.ch.basic.service.impl.BaseServiceImpl;
import cn.ch.basic.util.MD5Utils;
import cn.ch.basic.util.StrUtils;
import cn.ch.user.domain.Logininfo;
import cn.ch.user.domain.User;
import cn.ch.user.mapper.LogininfoMapper;
import cn.ch.user.mapper.UserMapper;
import cn.ch.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Why
 * @since 2022-02-14
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public void phoneRegister(RegisterDto dto) {
        //1.参数校验
        if(
                StringUtils.isEmpty(dto.getPhone())||
                StringUtils.isEmpty(dto.getPassword())||
                StringUtils.isEmpty(dto.getPasswordRepeat())||
                StringUtils.isEmpty(dto.getSmsCode())
        ){
            throw new BusinessException("参数有问题！！！");
        }
        //2.两次密码比较
        if (!dto.getPassword().equals(dto.getPasswordRepeat())) {
            throw new BusinessException("两次密码不一致，请重新输入!");
        }
        //3.验证码的比较是否正确
        String smsCodeKey = BaseConstant.RegisterConstant.BUSSINESS_REGISTER_PREFIX+dto.getPhone();//获取到的key（拼接后的）
        Object smsCodeTmp = redisTemplate.opsForValue().get(smsCodeKey);//获取到验证码，是拼接后的
        if(smsCodeTmp == null){
            throw new BusinessException("验证码已失效，请重新获取！");
        }
        String codeTmp = smsCodeTmp.toString().split(":")[0];//通过分割，获取四位数的验证码
        if(!dto.getSmsCode().equalsIgnoreCase(codeTmp)){//不区分大小写进行比较验证码
            throw new BusinessException("请填写正确的验证码！");
        }
        //4.把数据存储到t_user表和t_logininfo表
        User user = dto2user(dto);//获取方法里面的数据
        Logininfo logininfo = user2logininfo(user);//获取方法里面的数据
        logininfoMapper.save(logininfo);//把返回的数据存入到t_logininfo表里面
        user.setLogininfoId(logininfo.getId());//返回自增id --> 关联外键
        userMapper.save(user);//把数据存储到user表里面
    }

    /**
     * 把user中的数据传到logininfo里面
     * @param user
     * @return
     */
    private Logininfo user2logininfo(User user) {
        Logininfo logininfo = new Logininfo();//创建一个logininfo对象接收数据
        BeanUtils.copyProperties(user, logininfo);//使用BeanUtils里面的方法，将user获取到的内容，传到logininfo里面
        logininfo.setType(1);//要设置type的类型，用来区分用户还是管理员
        return logininfo;//返回数据
    }

    /**
     * 把接收到的数据，传入到user
     * @param dto
     * @return
     */
    private User dto2user(RegisterDto dto) {
        User user = new User();
        user.setUsername(dto.getPhone());//设置用户名
        user.setPhone(dto.getPhone());//设置手机号
        String salt = StrUtils.getComplexRandomString(32);//设置盐值
        user.setSalt(salt);//盐值
        String md5Pwd = MD5Utils.encrypByMd5(dto.getPassword() + salt);//使用盐值 加密 密码
        user.setPassword(md5Pwd);//设置密码

        return user;//把数据返回
    }

    @Override
    public void remove(Long id) {
        userMapper.delete(id);//根据id来删除
        User user = userMapper.loadById(id);//根据id查询对应user信息
        logininfoMapper.delete(user.getLogininfoId());//根据对应user获取到的外键id，来删除
    }
}
